package com.cskaoyan.service;

import com.cskaoyan.bean.*;
import com.cskaoyan.bo.CommentBO;
import com.cskaoyan.bo.CreateGoodsBO;
import com.cskaoyan.bo.SearchGoodsBO;
import com.cskaoyan.config.FileProperties;
import com.cskaoyan.mapper.*;
import com.cskaoyan.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author LiaoLong
 * @date 2021-05-09 14:49
 */
@Service
public class GoodsManagementServiceImpl implements GoodsManagementService {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private StorageMapper storageMapper;

    @Autowired
    private GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    private GoodsProductMapper goodsProductMapper;

    @Autowired
    private GoodsAttributeMapper goodsAttributeMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private FileProperties fileProperties;

    @Value("${host.address}")
    private String hostAddress;

    /**
     * 获取商品列表
     *
     * @param searchGoodsBO
     * @return
     */
    @Override
    public GoodsVO getGoods(SearchGoodsBO searchGoodsBO) {
        PageHelper.startPage(searchGoodsBO.getPage(), searchGoodsBO.getLimit());

        GoodsExample goodsExample = new GoodsExample();
        goodsExample.setOrderByClause(searchGoodsBO.getSort() + " " + searchGoodsBO.getOrder());
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        criteria.andDeletedNotEqualTo(true);

        // TODO: 如果业务扩展, 需要添加可供搜索的条件, 还是继续添加if语句吗?
        if (Objects.nonNull(searchGoodsBO.getGoodsSn())) {
            criteria.andGoodsSnLike("%" + searchGoodsBO.getGoodsSn() + "%");
        }
        if (Objects.nonNull(searchGoodsBO.getName())) {
            criteria.andNameLike("%" + searchGoodsBO.getName() + "%");
        }

        List<Goods> goods = goodsMapper.selectByExample(goodsExample);

        PageInfo<Goods> pageInfo = new PageInfo<>(goods);
        long total = pageInfo.getTotal();

        GoodsVO goodsVO = new GoodsVO();
        goodsVO.setTotal(total);
        goodsVO.setItems(goods);
        return goodsVO;
    }

    /**
     * 获取所有商品类目和品牌
     *
     * @return
     */
    @Override
    public CatAndBrandVO catAndBrand() {
        // 获取所有类目
        List<CategoryVO> categories = categoryMapper.selectByGroup();
        // 获取所有品牌列表
        List<BaseCatAndBrandVO> brands = brandMapper.selectAllBrandIdAndName();

        CatAndBrandVO catAndBrandVO = new CatAndBrandVO();
        catAndBrandVO.setCategoryList(categories);
        catAndBrandVO.setBrandList(brands);
        return catAndBrandVO;
    }

    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    @Transactional
    @Override
    public StorageVO fileupload(MultipartFile file, String fileSavePath) {
        String originalFilename = file.getOriginalFilename();
        String type = file.getContentType();
        int size = (int) file.getSize();
        String extension = originalFilename.substring(originalFilename.indexOf("."));
        String replaceFilename = UUID.randomUUID().toString().replace("-", "") + extension;


        File filepath = new File(fileSavePath, replaceFilename);

        if (! filepath.getParentFile().exists()){
            filepath.getParentFile().mkdirs();
        }
        try {
            file.transferTo(filepath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Date addTime = new Date();
        String url = hostAddress + fileProperties.getUrl() + replaceFilename;
        Storage storage = new Storage(null, replaceFilename, originalFilename, type, size, url, addTime, addTime, false);
        int count = storageMapper.insertAndReturnId(storage);

        return new StorageVO(storage.getId(), replaceFilename, originalFilename, type, size, url, addTime, addTime);
    }

    /**
     * 创建商品
     *
     * @param createGoodsBO
     */
    @Transactional
    @Override
    public void createGoods(CreateGoodsBO createGoodsBO) {
        // 插入数据到cskaoyanmall_goods表
        Goods goods = createGoodsBO.getGoods();
        Date addTime = new Date();
        goods.setAddTime(addTime);
        goods.setUpdateTime(addTime);
        goods.setDeleted(false);
        // TODO: sortOrder应该如何计算出来
        short sortOrder = 50;
        goods.setSortOrder(sortOrder);
        // TODO: 异常处理
        int count;
        count = goodsMapper.insertSelective(goods);
        Integer goodsId = goods.getId();


        // 插入数据到cskaoyanmall_goods_specification表
        List<GoodsSpecification> specifications = createGoodsBO.getSpecifications();
        for (GoodsSpecification specification : specifications) {
            specification.setGoodsId(goodsId);
            specification.setAddTime(addTime);
            specification.setUpdateTime(addTime);
            specification.setDeleted(false);
        }
        // TODO: 异常处理
        for (GoodsSpecification goodsSpecification : specifications) {
            count = goodsSpecificationMapper.insert(goodsSpecification);
        }

        // 插入数据到cskaoyanmall_goods_product表
        List<GoodsProduct> products = createGoodsBO.getProducts();
        for (GoodsProduct product : products) {
            product.setGoodsId(goodsId);
            product.setAddTime(addTime);
            product.setUpdateTime(addTime);
            product.setDeleted(false);
        }
        for (GoodsProduct goodsProduct : products) {
            count = goodsProductMapper.insert(goodsProduct);
        }

        // 插入数据到cskaoyanmall_goods_attributes表
        List<GoodsAttribute> attributes = createGoodsBO.getAttributes();
        for (GoodsAttribute attribute : attributes) {
            attribute.setGoodsId(goodsId);
            attribute.setAddTime(addTime);
            attribute.setUpdateTime(addTime);
            attribute.setDeleted(false);
        }
        // TODO: 异常处理
        for (GoodsAttribute goodsAttribute : attributes) {
            count = goodsAttributeMapper.insert(goodsAttribute);
        }
    }

    /**
     * 逻辑删除商品
     *
     * @param goods
     */
    @Override
    public void deleteGoods(Goods goods) {
        goods.setDeleted(true);
        GoodsExample goodsExample = new GoodsExample();
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        criteria.andIdEqualTo(goods.getId());
        goodsMapper.updateByExampleSelective(goods, goodsExample);
    }

    /**
     * 根据商品id获取商品类目, 商品信息, 商品属性, 商品规格, product
     *
     * @param goodsId 商品id
     * @return
     */
    @Transactional
    @Override
    public GoodsDetailVO getGoodsDetail(Integer goodsId) {
        GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
        // 获取商品
        Goods goods = goodsMapper.selectByPrimaryKey(goodsId);

        // 获取商品类目Id
        List<Integer> categoryIds = new ArrayList<>();
        // 这里这个是第二级类目id
        Integer categoryId = goods.getCategoryId();

        Category category = categoryMapper.selectByPrimaryKey(categoryId);

        try {
            Integer pid = category.getPid();
            categoryIds.add(pid);
        }catch (Exception e){
            // 异常抛出则该商品没有父级类目, 给默认值0
            categoryIds.add(0);
        }

        categoryIds.add(categoryId);

        // Attributes
        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<GoodsAttribute> goodsAttributes = goodsAttributeMapper.selectByExample(goodsAttributeExample);

        // products
        GoodsProductExample goodsProductExample = new GoodsProductExample();
        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(goodsProductExample);

        //  Specifications
        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<GoodsSpecification> goodsSpecifications = goodsSpecificationMapper.selectByExample(goodsSpecificationExample);


        // 封装到VO
        goodsDetailVO.setCategoryIds(categoryIds);
        goodsDetailVO.setGoods(goods);
        goodsDetailVO.setAttributes(goodsAttributes);
        goodsDetailVO.setProducts(goodsProducts);
        goodsDetailVO.setSpecifications(goodsSpecifications);
        return goodsDetailVO;
    }

    /**
     * 更新商品
     *
     * @param goodsDetailVO
     */
    @Transactional
    @Override
    public void updateGoods(GoodsDetailVO goodsDetailVO) {
        Goods goods = goodsDetailVO.getGoods();
        List<GoodsAttribute> attributes = goodsDetailVO.getAttributes();
        List<GoodsProduct> products = goodsDetailVO.getProducts();
        List<GoodsSpecification> specifications = goodsDetailVO.getSpecifications();

        Date updateTime = new Date();
        goods.setUpdateTime(updateTime);
        for (GoodsAttribute attribute : attributes) {
            attribute.setUpdateTime(updateTime);
        }
        for (GoodsProduct product : products) {
            product.setUpdateTime(updateTime);
        }
        for (GoodsSpecification specification : specifications) {
            specification.setUpdateTime(updateTime);
        }

        // 更新goods表
        goodsMapper.updateByPrimaryKey(goods);

        for (GoodsAttribute attribute : attributes) {
            goodsAttributeMapper.updateByPrimaryKey(attribute);
        }
        for (GoodsProduct product : products) {
            goodsProductMapper.updateByPrimaryKey(product);
        }
        for (GoodsSpecification specification : specifications) {
            goodsSpecificationMapper.updateByPrimaryKey(specification);
        }
    }

    /**
     * 获取所有评论
     *
     * @param commentBO
     * @return
     */
    @Override
    public CommentVO getComments(CommentBO commentBO) {
        PageHelper.startPage(commentBO.getPage(), commentBO.getLimit());

        CommentExample commentExample = new CommentExample();
        commentExample.setOrderByClause(commentBO.getSort() + " " + commentBO.getOrder());
        CommentExample.Criteria criteria = commentExample.createCriteria();
        criteria.andDeletedNotEqualTo(true);
        if (Objects.nonNull(commentBO.getUserId())) {
            criteria.andUserIdLike("%" + commentBO.getUserId() + "%");
        }
        if (Objects.nonNull(commentBO.getValueId())) {
            criteria.andValueIdLike("%" + commentBO.getValueId() + "%");
        }

        List<Comment> comments = commentMapper.selectByExample(commentExample);
        PageInfo<Comment> keywordPageInfo = new PageInfo<>(comments);
        long total = keywordPageInfo.getTotal();

        CommentVO commentVO = new CommentVO();
        commentVO.setItems(comments);
        commentVO.setTotal(total);
        return commentVO;
    }

    /**
     * 逻辑删除评论
     */
    @Transactional
    @Override
    public void deleteComment(Comment comment) {
        Date updateTime = new Date();
        Comment comment1 = new Comment();
        comment1.setId(comment.getId());
        comment1.setUpdateTime(updateTime);
        comment1.setDeleted(true);
        commentMapper.updateByPrimaryKeySelective(comment1);
    }
}
